package org.sws.infrastructure.persistent.repository;

import cn.bugstack.middleware.db.router.strategy.IDBRouterStrategy;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.support.TransactionTemplate;
import org.sws.domain.behavior.model.aggregate.BehaviorRebateAggregate;
import org.sws.domain.behavior.model.entity.BehaviorRebateConfigEntity;
import org.sws.domain.behavior.model.entity.BehaviorRebateOrderEntity;
import org.sws.domain.behavior.model.entity.BehaviorRebateTaskEntity;
import org.sws.domain.behavior.model.valobj.BehaviorTypeVO;
import org.sws.domain.behavior.repository.IBehaviorRebateRepository;
import org.sws.infrastructure.event.EventPublisher;
import org.sws.infrastructure.persistent.dao.IBehaviorRebateConfigDao;
import org.sws.infrastructure.persistent.dao.ITaskDao;
import org.sws.infrastructure.persistent.dao.IUserBehaviorRebateOrderDao;
import org.sws.infrastructure.persistent.po.Task;
import org.sws.infrastructure.persistent.po.UserBehaviorRebateOrder;
import org.sws.types.enums.ResponseCode;
import org.sws.types.exception.AppException;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Author sws
 * @Date 2025/3/27 11:46
 * @description:
 */
@Slf4j
@Repository
public class BehaviorRebateRepository implements IBehaviorRebateRepository {

    @Resource
    private IBehaviorRebateConfigDao behaviorRebateConfigDao;
    @Resource
    private IUserBehaviorRebateOrderDao userBehaviorRebateOrderDao;
    @Resource
    private ITaskDao taskDao;
    @Resource
    private IDBRouterStrategy dbRouter;
    @Resource
    private TransactionTemplate transactionTemplate;
    @Resource
    private ThreadPoolExecutor threadExecutor;
    @Resource
    private EventPublisher eventPublisher;
    @Override
    public List<BehaviorRebateConfigEntity> queryBehaviorRebateConfig(String typeCode) {
       return behaviorRebateConfigDao.queryBehaviorRebateConfig(typeCode);
    }

    @Override
    public void saveUserRebateRecord(String userId, List<BehaviorRebateAggregate> behaviorRebateAggregates) {
        // 构建数据库po对象
        List<UserBehaviorRebateOrder> userBehaviorRebateOrders = new ArrayList<>(behaviorRebateAggregates.size());
        List<Task> taskList = new ArrayList<>(behaviorRebateAggregates.size());
        for (BehaviorRebateAggregate behaviorRebateAggregate : behaviorRebateAggregates) {
            BehaviorRebateOrderEntity behaviorRebateOrderEntity = behaviorRebateAggregate.getBehaviorRebateOrderEntity();
            // 用户行为返利订单对象
            UserBehaviorRebateOrder userBehaviorRebateOrder = new UserBehaviorRebateOrder();
            userBehaviorRebateOrder.setUserId(behaviorRebateOrderEntity.getUserId());
            userBehaviorRebateOrder.setOrderId(behaviorRebateOrderEntity.getOrderId());
            userBehaviorRebateOrder.setBehaviorType(behaviorRebateOrderEntity.getBehaviorType());
            userBehaviorRebateOrder.setRebateDesc(behaviorRebateOrderEntity.getRebateDesc());
            userBehaviorRebateOrder.setRebateType(behaviorRebateOrderEntity.getRebateType());
            userBehaviorRebateOrder.setRebateConfig(behaviorRebateOrderEntity.getRebateConfig());
            userBehaviorRebateOrder.setBizId(behaviorRebateOrderEntity.getBizId());
            userBehaviorRebateOrders.add(userBehaviorRebateOrder);

            BehaviorRebateTaskEntity taskEntity = behaviorRebateAggregate.getBehaviorRebateTaskEntity();
            Task task = new Task();
            task.setUserId(taskEntity.getUserId());
            task.setTopic(taskEntity.getTopic());
            task.setMessageId(taskEntity.getMessageId());
            task.setMessage(JSON.toJSONString(taskEntity.getMessage()));
            task.setState(taskEntity.getState().getCode());
            taskList.add(task);
        }
        try {
            dbRouter.doRouter(userId);
            transactionTemplate.execute(status -> {
                try {
                    int count = userBehaviorRebateOrderDao.insertBatch(userBehaviorRebateOrders);
                    taskDao.insertBatch(taskList);
                    return count;
                }catch (DuplicateKeyException e){
                    status.setRollbackOnly();
                    log.warn("保存用户行为返利记录失败，唯一索引冲突 userId: {}", userId, e);
                    throw new AppException(ResponseCode.INDEX_DUP.getCode(), "今日已签到");
                }catch (Exception e) {
                    status.setRollbackOnly();
                    log.error("保存用户行为返利记录失败，userId: {}", userId, e);
                    throw new RuntimeException(e);
                }
            });
        } finally {
            dbRouter.clear();
        }

        // 异步发送MQ消息
        eventPublisher.syncPublish(taskList);
    }

    @Override
    public Boolean isCalendarSignRebate(String userId, String outBusinessNo) {
        UserBehaviorRebateOrder userBehaviorRebateOrder = new UserBehaviorRebateOrder();
        userBehaviorRebateOrder.setUserId(userId);
        userBehaviorRebateOrder.setBehaviorType(BehaviorTypeVO.SIGN.getCode());
        // 按照右匹配 匹配拼接的outBusinessNo
        userBehaviorRebateOrder.setBizId(outBusinessNo);
        int record = userBehaviorRebateOrderDao.queryCurrentOrderRecord(userBehaviorRebateOrder);
        if (record > 0) {
            return true;
        } else {
            return false;
        }
    }

}
